﻿using System;
using System.Linq;
using System.Web.Mvc;
using QDT.Common;
using QDT.Core.Orders;
using QDT.Core.Payments;
using QDT.MVC;
using QDT.MVC.Security;
using QDT.Payment;
using QDT.Services.Orders;
using QDT.Web.Code;
using QDT.Web.Models;

namespace QDT.Web.Controllers
{
    public class PaymentController : BaseController
    {

        private readonly IOrderService _orderService;
        private readonly IPayment _payment;

        public PaymentController(IOrderService orderService, IPayment payment)
        {
            _orderService = orderService;
            _payment = payment;
        }

        [DefaultAuthorize]
        public ActionResult Pay(int orderId)
        {
            var order = DbProvider.GetByID<ChargeOrder>(orderId);
            var user = QDTContext.Current.User;

            if (order == null) return Error("支付订单不存在，或者已经失效.");

            PaymentNotice notice = _orderService.CreatePaymentOrder(orderId);

            _payment.InchargeRequest((new PaymentOrder
            {
                BankCode = order.BankCode,
                Money = notice.Money,
                PaymentNo = notice.NoticeSn,
                ReturnUrl = Url.AbsoluteAction("Notice"),
                NoticeUrl = Url.AbsoluteAction("AutoNotice"),
                UserName = user.RealName,
                UserIDCard = user.IDCard,
                CreateTime = order.CreateTime
            }));

            return Content("");
        }

        [DefaultAuthorize]
        public ActionResult OfflinePay(int orderId, string name)
        {
            if (string.IsNullOrWhiteSpace(name)) return Error("持卡人输入错误");

            var order = DbProvider.GetByID<ChargeOrder>(orderId);

            if (order == null) return Error("支付订单不存在，或者已经失效.");

            PaymentNotice notice = _orderService.CreatePaymentOrder(orderId);

            ViewBag.Name = name;

            return View("OfflinePayment", notice);
        }

        public ActionResult Notice(FormCollection form)
        {

            if (form.Keys.Count==0)
            {
                return Error("未知异常");
            }

            string returnContent = "";

            bool isOk = VerifyNotify(form, out returnContent);

            return isOk ? Success("充值成功", "恭喜您充值成功", Url.Action("Index", "Home")) : Message(new MessageModel
            {
                JumpUrl = Url.Action("Index", "Home"),
                Message = "充值失败",
                Title = "充值失败",
                Type = false,
                WaitSecond = 60
            });
        }

        /// <summary>
        /// 自动回复
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        public ActionResult AutoNotice(FormCollection form)
        {
            if (form.Keys.Count == 0)
            {
                return Error("未知异常");
            }

            string returnContent = "";

            bool isOK = VerifyNotify(form, out returnContent);

            Log.Info("通过第三方自动返回充值");

            return Content(returnContent);

        }

        [HttpPost]
        [DefaultAuthorize]
        [ValidateAntiForgeryToken]
        public ActionResult OfflineNotice(string noticeSn, decimal money, string token, string payCode, string codeExplain)
        {

            if (payCode=="00" && codeExplain.Contains("交易成功"))
            {
                var order = new PaymentOrder
                {
                    PaymentNo = noticeSn,
                    Money = money
                };
                _orderService.PayFinished(order);
                Log.Info("通过第三方自动返回充值");

                return Success("", codeExplain, Url.Action("Index", "User"));
            }

            return Error("", codeExplain, Url.Action("Index", "User"));

        }

        private static readonly object _asnyLock = new object();

        private bool VerifyNotify(FormCollection form, out string returnContent)
        {
            lock (_asnyLock)
            {
                returnContent = "";
                object order;

                bool isOk = _payment.VerifyNotify(form, out returnContent,out order);

                if (isOk)
                {
                    _orderService.PayFinished(order);
                } else
                {
                    _orderService.PayFaild(order);
                }

                return isOk;
            }

        }

    }
}
